package cn.edu.ncu.housinghub.service.impl;

import cn.edu.ncu.housinghub.dto.chat.ChatMessageDTO;
import cn.edu.ncu.housinghub.entity.chatsession.ChatMessage;
import cn.edu.ncu.housinghub.entity.chatsession.ChatSession;
import cn.edu.ncu.housinghub.mapper.chat.ChatMessageMapper;
import cn.edu.ncu.housinghub.mapper.chat.ChatSessionMapper;
import cn.edu.ncu.housinghub.service.ChatService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static cn.edu.ncu.housinghub.config.RabbitMQConfig.CHAT_MESSAGE_QUEUE;


@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements ChatService {

    private final ChatSessionMapper chatSessionMapper;
    private final ChatMessageMapper chatMessageMapper;
    private final RabbitTemplate rabbitTemplate;
    private final RedisTemplate<String, Object> redisTemplate;

    // Redis中未读消息的key前缀
    private static final String UNREAD_COUNT_PREFIX = "chat:unread:";

    @Override
    public ChatSession getOrCreateSession(Long userId1, Long userId2, Long houseId) {
        // 确保userId1小于userId2，避免重复创建会话
        if (userId1 > userId2) {
            Long temp = userId1;
            userId1 = userId2;
            userId2 = temp;
        }

        // 查询是否已有会话
        ChatSession session = chatSessionMapper.getSessionByUsers(userId1, userId2, houseId);

        if (session == null) {
            // 不存在则创建新会话
            session = new ChatSession();
            session.setUserId1(userId1);
            session.setUserId2(userId2);
            session.setHouseId(houseId);
            session.setStatus(0);
            session.setLastTime(LocalDateTime.now());
            chatSessionMapper.createSession(session);
        }

        return session;
    }

    @Override
    @Transactional
    public ChatMessage sendMessage(Long senderId, ChatMessageDTO messageDTO) {
        // 获取或创建会话
        ChatSession session = getOrCreateSession(senderId, messageDTO.getReceiverId(), messageDTO.getHouseId());

        // 创建消息
        ChatMessage message = new ChatMessage();
        message.setSessionId(session.getSessionId());
        message.setSenderId(senderId);
        message.setReceiverId(messageDTO.getReceiverId());
        message.setContent(messageDTO.getContent());
        message.setMessageType(messageDTO.getType());
        message.setIsRead(0); // 未读
        message.setSendTime(LocalDateTime.now());

        // 保存消息到数据库
        int result = chatMessageMapper.saveMessage(message);
        System.out.println("消息保存结果: " + result + ", 消息ID: " + message.getMessageId());

        // 更新会话最后消息
        chatSessionMapper.updateLastMessage(session.getSessionId(), messageDTO.getContent());

        // 发送消息到RabbitMQ队列，由消息消费者处理推送
        try {
            rabbitTemplate.convertAndSend(CHAT_MESSAGE_QUEUE, message);
            System.out.println("消息已发送到RabbitMQ队列");
        } catch (Exception e) {
            System.err.println("RabbitMQ发送失败: " + e.getMessage());
            // RabbitMQ失败不影响消息保存
        }

        // 更新Redis中的未读消息计数
        try {
            String unreadKey = UNREAD_COUNT_PREFIX + session.getSessionId() + ":" + messageDTO.getReceiverId();
            redisTemplate.opsForValue().increment(unreadKey);
            redisTemplate.expire(unreadKey, 7, TimeUnit.DAYS);
        } catch (Exception e) {
            System.err.println("Redis操作失败: " + e.getMessage());
            // Redis失败不影响消息发送
        }

        return message;
    }

    @Override
    public List<ChatMessage> getSessionMessages(Long sessionId, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        return chatMessageMapper.getMessagesBySessionId(sessionId, offset, pageSize);
    }

    @Override
    public List<ChatSession> getUserSessions(Long userId) {
        return chatSessionMapper.getUserSessions(userId);
    }

    @Override
    @Transactional
    public void markAsRead(Long sessionId, Long receiverId) {
        // 更新数据库中消息状态
        chatMessageMapper.updateMessageStatus(sessionId, receiverId);

        // 清除Redis中的未读计数
        String unreadKey = UNREAD_COUNT_PREFIX + sessionId + ":" + receiverId;
        redisTemplate.delete(unreadKey);
    }

    @Override
    public int getUnreadCount(Long sessionId, Long receiverId) {
        String unreadKey = UNREAD_COUNT_PREFIX + sessionId + ":" + receiverId;
        Object count = redisTemplate.opsForValue().get(unreadKey);
        return count != null ? Integer.parseInt(count.toString()) : 0;
    }
}